home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
adg_1_3.zip
/
DLG-DYNA.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-21
|
14KB
|
422 lines
/****************************************************************************
Module name: Dlg-Dyna.C
Programmer : Jeffrey M. Richter.
*****************************************************************************/
#include "..\nowindws.h"
#undef NOCTLMGR
#undef NOKERNEL
#undef NOLSTRING
#undef NOMEMMGR
#undef NOUSER
#undef NOWINMESSAGES
#undef NOWINSTYLES
#include <windows.h>
#include <memory.h>
#include "dlg-dyna.h"
typedef struct {
long dtStyle;
BYTE dtItemCount;
int dtX;
int dtY;
int dtCX;
int dtCY;
// char dtMenuName[]; // Variable-length string.
// char dtClassName[]; // Variable-length string.
// char dtCaptionText[]; // Variable-length string.
} DLGTEMPLATE, FAR *LPDLGTEMPLATE;
typedef struct {
short int PointSize;
// char szTypeFace[]; // Variable-length string.
} FONTINFO, FAR *LPFONTINFO;
typedef struct {
int dtilX;
int dtilY;
int dtilCX;
int dtilCY;
int dtilID;
long dtilStyle;
// char dtilClass[]; // Variable-length string.
// char dtilText[]; // Variable-length string.
// BYTE dtilInfo; // # of bytes in following memory block.
// BYTE dtilData; // Variable-length memory block.
} DLGITEMTEMPLATE, FAR *LPDLGITEMTEMPLATE;
GLOBALHANDLE FAR PASCAL CreateDlgTemplate(
LONG dtStyle,
int dtX, int dtY, // In dialog-box units
int dtCX, int dtCY, // In dialog-box units
LPSTR dtMenuName, // "" if no menu
LPSTR dtClassName, // "" if standard dialog box class
LPSTR dtCaptionText,
short int PointSize, // Only used if DS_SETFONT style specified
LPSTR szTypeFace) { // Only used if DS_SETFONT style specified
GLOBALHANDLE hMem;
WORD wBlockLen, FAR *wNumBytes;
WORD wMenuNameLen, wClassNameLen, wCaptionTextLen, wTypeFaceLen;
LPSTR szDlgTemplate, szDlgTypeFace;
LPDLGTEMPLATE lpDlgTemplate;
LPFONTINFO lpFontInfo;
// Calculate number of bytes required by following fields:
wMenuNameLen = 1 + lstrlen(dtMenuName);
wClassNameLen = 1 + lstrlen(dtClassName);
wCaptionTextLen = 1 + lstrlen(dtCaptionText);
// Block must be large enough to contain the following:
wBlockLen =
sizeof(WORD) + // Stores # of bytes used in block.
sizeof(DLGTEMPLATE) + // # bytes for fixed part of DLGTEMPLATE.
wMenuNameLen + // # bytes for menu name.
wClassNameLen + // # bytes for dialog class name.
wCaptionTextLen; // # bytes for dialog box caption.
if (dtStyle & DS_SETFONT) {
// Dialog box uses font other that System font.
// Calculate # of bytes required for typeface name.
wTypeFaceLen = 1 + lstrlen(szTypeFace);
// Block must be large enough to include font information.
wBlockLen +=
sizeof(short int) + // # bytes for font's point size.
wTypeFaceLen; // # bytes for font typeface name.
} else {
// Dialog box uses the System font.
wTypeFaceLen = 0;
// Block length does not change.
}
// Allocate global block of memory for Dialog template.
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, wBlockLen);
if (hMem == NULL) return(hMem);
// wNumBytes points to beginning of memory block.
wNumBytes = (WORD FAR *) GlobalLock(hMem);
// Store in the first two bytes the number of bytes used in the block.
*wNumBytes = (WORD) wBlockLen;
// lpDlgTemplate points to start of DLGTEMPLATE in block.
lpDlgTemplate = (LPDLGTEMPLATE) (wNumBytes + 1);
// Set the members of the DLGTEMPLATE structure.
lpDlgTemplate->dtStyle = dtStyle;
lpDlgTemplate->dtItemCount = 0; // Incremented with calls to AddDlgItem.
lpDlgTemplate->dtX = dtX;
lpDlgTemplate->dtY = dtY;
lpDlgTemplate->dtCX = dtCX;
lpDlgTemplate->dtCY = dtCY;
// szDlgTemplate points to start of variable part of DLGTEMPLATE.
szDlgTemplate = (LPSTR) (lpDlgTemplate + 1);
// Append the menu name, class name, and caption text to the block.
_fmemcpy(szDlgTemplate, dtMenuName, wMenuNameLen);
szDlgTemplate += wMenuNameLen;
_fmemcpy(szDlgTemplate, dtClassName, wClassNameLen);
szDlgTemplate += wClassNameLen;
_fmemcpy(szDlgTemplate, dtCaptionText, wCaptionTextLen);
szDlgTemplate += wCaptionTextLen;
if (dtStyle & DS_SETFONT) {
// Dialog box uses font other that System font.
// lpFontInfo points to start of FONTINFO structure in block.
lpFontInfo = (LPFONTINFO) szDlgTemplate;
// Set the members of the FONTINFO structure.
lpFontInfo->PointSize = PointSize;
// szTypeFace points to start of variable part of FONTINFO.
szDlgTypeFace = (LPSTR) (lpFontInfo + 1);
// Append the typeface name to the block.
_fmemcpy(szDlgTypeFace, szTypeFace, wTypeFaceLen);
}
GlobalUnlock(hMem);
return(hMem);
}
// LOWORD = Success(TRUE)/Failure(FALSE), HIWORD=New hMem
DWORD FAR PASCAL AddDlgControl (
GLOBALHANDLE hMem, // Handle from CreateDlgData or AddDlgItem.
int dtilX, int dtilY, // In dialog-box units.
int dtilCX, int dtilCY, // In dialog-box units.
int dtilID,
long dtilStyle, // WS_CHILD is automatically added.
LPSTR dtilClass, // May be: "BUTTON", "EDIT", "STATIC",
// "LISTBOX", "SCROLLBAR", "COMBOBOX".
LPSTR dtilText,
BYTE dtilInfo, // Number of additional data bytes.
LPBYTE dtilData) { // Value passed through lpCreateParams field.
// of CREATESTRUCT.
GLOBALHANDLE hMemNew;
WORD wBlockLen, wClassLen, wTextLen, FAR *wNumBytes;
LPDLGTEMPLATE lpDlgTemplate;
LPDLGITEMTEMPLATE lpDlgItemTemplate;
LPSTR szDlgItemTemplate;
// Calculate number of bytes required by following fields:
wClassLen = 1 + lstrlen(dtilClass);
wTextLen = 1 + lstrlen(dtilText);
// Block must be increased by to contain the following:
wBlockLen =
sizeof(DLGITEMTEMPLATE) + // # bytes for fixed part of DLGITEMTEMPLATE.
wClassLen + // # bytes for control class.
wTextLen + // # bytes for control text.
sizeof(BYTE) + // 1 byte for # of dtilInfo bytes (below).
dtilInfo; // # bytes for extra data.
// Guarantee that all controls have WS_CHILD style.
dtilStyle |= WS_CHILD;
// Get number of bytes currently in the memory block.
wBlockLen += * (WORD FAR *) GlobalLock(hMem);
GlobalUnlock(hMem);
// Increase the size of the memory block to include the new dialog item.
hMemNew = GlobalReAlloc(hMem, wBlockLen, GMEM_MOVEABLE | GMEM_ZEROINIT);
if (hMemNew == NULL)
return(MAKELONG(FALSE, hMem));
// wNumBytes points to beginning of memory block.
wNumBytes = (WORD FAR *) GlobalLock(hMemNew);
// lpDlgTemplate points to start of DLGTEMPLATE in block.
lpDlgTemplate = (LPDLGTEMPLATE) (wNumBytes + 1);
// Increment the number of controls in the template.
lpDlgTemplate->dtItemCount++;
// lpDlgItemTemplate points to start of new DLGITEMTEMPLATE in block.
// This is at the end of the memory block.
lpDlgItemTemplate = (LPDLGITEMTEMPLATE) (((LPSTR) wNumBytes) + *wNumBytes);
// Set the members of the DLGITEMTEMPLATE structure.
lpDlgItemTemplate->dtilX = dtilX;
lpDlgItemTemplate->dtilY = dtilY;
lpDlgItemTemplate->dtilCX = dtilCX;
lpDlgItemTemplate->dtilCY = dtilCY;
lpDlgItemTemplate->dtilID = dtilID;
lpDlgItemTemplate->dtilStyle = dtilStyle;
// szDlgTemplate points to start of variable part of DLGITEMTEMPLATE.
szDlgItemTemplate = (LPSTR) (lpDlgItemTemplate + 1);
// Append the control's class name, text to the block.
_fmemcpy(szDlgItemTemplate, dtilClass, wClassLen);
szDlgItemTemplate += wClassLen;
_fmemcpy(szDlgItemTemplate, dtilText, wTextLen);
szDlgItemTemplate += wTextLen;
// Append the control's dtilInfo member.
*szDlgItemTemplate = dtilInfo;
szDlgItemTemplate += sizeof(BYTE);
// Append the control's dtilData member.
_fmemcpy(szDlgItemTemplate, dtilData, dtilInfo);
szDlgItemTemplate += dtilInfo;
// Store in the first two bytes the number of bytes used in the block.
*wNumBytes = (WORD) (szDlgItemTemplate - (LPSTR) wNumBytes);
GlobalUnlock(hMemNew);
return(MAKELONG(TRUE, hMemNew));
}
void FAR PASCAL DoneAddingControls (GLOBALHANDLE hMem) {
WORD FAR *wNumBytes;
// wNumBytes points to beginning of memory block.
wNumBytes = (WORD FAR *) GlobalLock(hMem);
// Move all of the bytes in the block down two bytes.
_fmemcpy(wNumBytes, wNumBytes + 1, *wNumBytes - 2);
GlobalUnlock(hMem);
// Once this function is executed, no more items can be
// added to the dialog box template.
}
#ifdef _DEMO
//****************************************************************************
// Functions for the Dynamic Modal and Modeless Dialog Box demonstrations.
#include "dialog.h"
#define MAXDLGITEMDATA (10)
struct {
int x, y, cx, cy, id;
long Style;
LPSTR szClass, szText;
BYTE Info;
BYTE Data[MAXDLGITEMDATA];
} DynamicDlgBoxData[] = {
{ 4, 4, 32, 12, -1, SS_LEFT, "STATIC", "&Edit box:", 0, { 0 } },
{ 40, 4, 64, 12, ID_EDITBOX,
ES_LEFT | WS_BORDER | WS_TABSTOP | WS_GROUP, "EDIT", "", 0, { 0 } },
{ 4, 18, 40, 8, -1, SS_LEFT, "STATIC", "&Listbox:", 0, { 0 } },
{ 4, 28, 76, 41, ID_LISTBOX, LBS_NOTIFY | LBS_SORT | LBS_STANDARD |
WS_BORDER | WS_VSCROLL | WS_TABSTOP | WS_GROUP, "LISTBOX", "", 0, { 0 } },
{ 132, 4, 36, 12, IDOK, BS_DEFPUSHBUTTON | WS_TABSTOP | WS_GROUP,
"BUTTON", "&Ok", 0, { 0 } },
{ 176, 4, 36, 12, IDCANCEL, BS_PUSHBUTTON | WS_TABSTOP | WS_GROUP,
"BUTTON", "&Cancel", 0, { 0 } },
{ 88, 24, 56, 44, -1, BS_GROUPBOX | WS_GROUP, "BUTTON", "Group box", 0, { 0 } },
{ 92, 36, 48, 12, ID_RADIO1, BS_RADIOBUTTON | WS_TABSTOP,
"BUTTON", "Radio &1", 0, { 0 } },
{ 92, 48, 48, 12, ID_RADIO2, BS_RADIOBUTTON | WS_TABSTOP,
"BUTTON", "Radio &2", 0, { 0 } },
{ 152, 32, 60, 12, ID_CHECKBOX, BS_CHECKBOX | WS_TABSTOP | WS_GROUP,
"BUTTON", "C&heck box", 0, { 0 } },
{ 0, 0, 0, 0, 0, 0, NULL, NULL, 0, { 0 } }
};
BOOL FAR PASCAL DynamicDlgProc (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam) {
BOOL fProcessed = TRUE;
switch (wMsg) {
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch (wParam) {
case IDOK:
case IDCANCEL:
// Although the two push buttons for IDOK and IDCANCEL are
// not included in the modeless version of this dialog box,
// these options can still come through to here if the user
// presses the "Enter" or "Esc" keys respectively.
// In the case of a modeless dialog box we cannot call the
// EndDialog() function. We can determine if this window is
// the modeless one because it does not have the IDOK button
// within it. In this case, GetDlgItem() below returns NULL.
if (GetDlgItem(hDlg, IDOK) == NULL)
break;
if (HIWORD(lParam) == BN_CLICKED)
EndDialog(hDlg, wParam);
break;
default:
break;
}
break;
default:
fProcessed = FALSE; break;
}
return(fProcessed);
}
GLOBALHANDLE FAR PASCAL BuildDynamicDlgBox (BOOL fModeless) {
GLOBALHANDLE hMem;
WORD x;
DWORD dwAddDlgControlResult;
// Create the dynamic dialog box header information.
if (fModeless)
hMem = CreateDlgTemplate(
WS_BORDER | WS_CAPTION | WS_DLGFRAME |
WS_SYSMENU | WS_VISIBLE | WS_POPUP | DS_SETFONT,
6, 25, 216, 72, "", "", "Dynamic Modeless Demo", 8, "Helv");
else
hMem = CreateDlgTemplate(
WS_BORDER | WS_CAPTION | WS_DLGFRAME |
WS_SYSMENU | WS_VISIBLE | WS_POPUP,
6, 25, 216, 72, "", "", "Dynamic Modal Demo", 0, "");
if (hMem == NULL)
return(hMem);
// Add each of the controls in the DynamicDlgBoxData array.
for (x = 0; DynamicDlgBoxData[x].szClass != NULL; x++) {
// Do not add the "Ok" and "Cancel" buttons if a modeless dialog
// box is being created.
if (fModeless) {
if (DynamicDlgBoxData[x].id == IDOK ||
DynamicDlgBoxData[x].id == IDCANCEL)
continue;
}
dwAddDlgControlResult = AddDlgControl(hMem,
DynamicDlgBoxData[x].x, DynamicDlgBoxData[x].y,
DynamicDlgBoxData[x].cx, DynamicDlgBoxData[x].cy,
DynamicDlgBoxData[x].id,
DynamicDlgBoxData[x].Style | WS_VISIBLE,
DynamicDlgBoxData[x].szClass, DynamicDlgBoxData[x].szText,
DynamicDlgBoxData[x].Info, DynamicDlgBoxData[x].Data);
// LOWORD is FALSE if insufficient memory exists.
if (LOWORD(dwAddDlgControlResult) == FALSE) break;
// HIWORD is handle to new block of memory.
hMem = HIWORD(dwAddDlgControlResult);
}
// LOWORD is FALSE if insufficient memory exists, free what we have and
// return NULL to caller.
if (LOWORD(dwAddDlgControlResult) == FALSE) {
GlobalFree(hMem);
hMem = NULL;
} else {
// Cleanup the dialog box information.
DoneAddingControls(hMem);
}
// Return the handle to the dynamic dialog box information.
return(hMem);
}
#endif